package com.cy.sys.service.relam;

import com.cy.sys.dao.SysUserDao;
import com.cy.sys.pojo.SysUser;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

//AuthorizingRealm extends AuthenticatingRealm

/**
 *定义shiro realm对象，基于此对象获取用户认证和授权信息
 * 假如将来你的项目制作认证，不做授权，
 */
public class ShiroRealm extends AuthorizingRealm {
    @Autowired
    private SysUserDao sysUserDao;

    /**
     * 获取并封装授权信息
     *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        return null;
    }

    /**
     *获取并封装认证信息f
     * @param authenticationToken 为封装了客户端认证信息的一个令牌对象
     * @return
     * @throws AuthenticationException
     */
    @Override
//    进入到AuthenticationInfo ctrl+h看实现类
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //通过转换成UsernamePasswordToken获取客户端的userName
        UsernamePasswordToken upToken = (UsernamePasswordToken) authenticationToken;
        String username = upToken.getUsername();
        //基于用户查询用户信息 （编程时第一步在这个是因为确认目标通过目标分析）
       SysUser user = sysUserDao.selectUserByUsername(username);
        if (user== null)throw  new UnknownAccountException();
        if (user.getValid()==0)throw new LockedAccountException();

//        3、封装用户信息 (若通过无参构造方法创建对象可以用set来赋值 ，也可以用有参构造创建)
        ByteSource credentialsSalt = ByteSource.Util.bytes(user.getSalt());
        String realmName=getName();
        System.out.println("realname"+realmName);
        return new SimpleAuthenticationInfo(user,//principal 身份（基于业务设置 查询到的用户信息 ）
                user.getPassword(),//hashedCredentials 加密的凭证 (数据库存储的密码)
                credentialsSalt,// credentialsSalt （凭证盐）底层对其做了编码处理的加密盐对象
                this.getName());//realmName 获取当前这个类的名字

    }

    /**
     * 重写此方法的目的是，底层对用户输入的登陆密码进行加密，需要算法
     * @return
     */
    @Override
    public CredentialsMatcher getCredentialsMatcher() {
        HashedCredentialsMatcher credentialsMatcher=
                new HashedCredentialsMatcher("MD5");
        credentialsMatcher.setHashIterations(1);
        return credentialsMatcher;
    }
//    public ShiroRealm(){
//        HashedCredentialsMatcher credentialsMatcher=
//                new HashedCredentialsMatcher("MD5");
//        credentialsMatcher.setHashIterations(1);
//        setCredentialsMatcher(credentialsMatcher);
//    }
}
